package com.tiancheng.trade.settlement.service.settlement.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiancheng.trade.settlement.enums.PayWayEnum;
import com.tiancheng.trade.settlement.enums.PaymentChannelEnum;
import com.tiancheng.trade.settlement.enums.TransactionTypeEnum;
import com.tiancheng.trade.settlement.mapper.settlement.PaymentOrderBankBatch;
import com.tiancheng.trade.settlement.mapper.settlement.PaymentOrderBankDetailBatch;
import com.tiancheng.trade.settlement.mapper.settlement.PaymentOrderBankDetailMapper;
import com.tiancheng.trade.settlement.mapper.settlement.PaymentOrderBankMapper;
import com.tiancheng.trade.settlement.model.settlement.PaymentBankDataCmb;
import com.tiancheng.trade.settlement.model.settlement.PaymentOrderBank;
import com.tiancheng.trade.settlement.model.settlement.PaymentOrderBankDetail;
import com.tiancheng.trade.settlement.service.settlement.IPaymentBankDataService;
import com.tiancheng.trade.settlement.util.EnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 支付流水对账
 */
@Service
@Slf4j
public class PaymentBankDataService implements IPaymentBankDataService {

    @Autowired
    PaymentOrderBankMapper paymentOrderBankMapper;

    @Autowired
    PaymentOrderBankBatch paymentOrderBankBatch;

    @Autowired
    PaymentOrderBankDetailMapper paymentOrderBankDetailMapper;

    @Autowired
    PaymentOrderBankDetailBatch paymentOrderBankDetailBatch;

    @Resource
    private RedissonClient redissonClient;

    /**
     * 招商银行获取需要保存的数据(待对账银行侧流水)
     *
     * @param list 招商支付对账明细数据
     * @return
     */
    private List<PaymentOrderBank> getPaymentOrderBankFromCmb(List<PaymentBankDataCmb> list) {
        List<PaymentOrderBank> listSave = new ArrayList<>();

        for (PaymentBankDataCmb detailCmb : list) {
            PaymentOrderBank paymentOrderBank = getPaymentOrderBank(detailCmb.getBankSerialNumber());
            if (paymentOrderBank == null) {
                PaymentOrderBank paymentOrderBankAdd = new PaymentOrderBank();
                paymentOrderBankAdd.setFlowId(detailCmb.getThirdOrderNo());
                paymentOrderBankAdd.setPayChannelOrderid(detailCmb.getBankSerialNumber());
                String strTransactionType = detailCmb.getTransactionType();
                String transactionType = "";
                TransactionTypeEnum transactionTypeEnum = EnumUtil.getEnumByDesc(TransactionTypeEnum.class, strTransactionType);
                if (transactionTypeEnum == null) {
                    log.warn("交易类型(" + strTransactionType + ")在枚举中不存在，请检查和添加！");
                } else {
                    transactionType = transactionTypeEnum.getCode();
                }
                paymentOrderBankAdd.setTransactionType(transactionType);
                paymentOrderBankAdd.setPayTime(detailCmb.getTransactionDatetime());
                paymentOrderBankAdd.setPayAmount(detailCmb.getTransactionAmount());
                paymentOrderBankAdd.setOrderAmount(detailCmb.getOriginalOrderAmount());
                paymentOrderBankAdd.setSettlementAmount(detailCmb.getSettlementAmount());
                paymentOrderBankAdd.setServiceCharge(detailCmb.getServiceCharge());
                paymentOrderBankAdd.setDiscount(detailCmb.getPlatformPreferentialAmount() == null ? 0 : detailCmb.getPlatformPreferentialAmount());
                paymentOrderBankAdd.setRate(detailCmb.getRate());
                listSave.add(paymentOrderBankAdd);
            }
        }
        return listSave;
    }

    /**
     * 查询待对账银行侧流水
     *
     * @param payChannelOrderid 银行流水号
     * @return
     */
    private PaymentOrderBank getPaymentOrderBank(String payChannelOrderid) {
        QueryWrapper<PaymentOrderBank> conditions = new QueryWrapper<>();
        conditions.eq("pay_channel_orderid", payChannelOrderid);
        return paymentOrderBankMapper.selectOne(conditions);
    }

    /**
     * 保存待对账银行侧流水
     *
     * @param list 招商支付对账明细数据
     */
    public boolean savePaymentOrderBankBatch(List<PaymentBankDataCmb> list) {
  /*      List<PaymentOrderBank> listSave = getPaymentOrderBankFromCmb(list);
        if (listSave == null || listSave.size() == 0) {
            log.info("待对账银行侧流水没有数据需要保存.");
        } else {
            RLock lock = redissonClient.getLock("PAYMENT_ORDER_BANK_BATCH");
            try {
                lock.lock();*/
        List<PaymentOrderBank> listSaveBatch = getPaymentOrderBankFromCmb(list);
        if (listSaveBatch == null || listSaveBatch.size() == 0) {
            log.info("待对账银行侧流水没有数据需要保存");
        } else {
            boolean bo = paymentOrderBankBatch.saveBatch(listSaveBatch);
            if (bo) {
                log.info("待对账银行侧流水数据保存成功");
            } else {
                log.warn("待对账银行侧流水数据保存失败");
            }
            return bo;
        }
           /* } catch (Exception e) {
                log.error("保存待对账银行侧流水数据,出现异常：{}", e.getMessage());
            } finally {
                lock.forceUnlock();
            }
        }*/
        return false;
    }

    /**
     * 保存对账流水详情
     *
     * @param list 招商支付对账明细数据
     */
    public boolean savePaymentOrderBankDetailBatch(List<PaymentBankDataCmb> list) {
    /*    List<PaymentOrderBankDetail> listSave = getPaymentOrderBankDetailFromCmb(list);
        if (listSave == null || listSave.size() == 0) {
            log.info("对账流水详情没有数据需要保存.");
        } else {
            RLock lock = redissonClient.getLock("PAYMENT_ORDER_BANK_DETAIL_BATCH");*/
        try {
            //  lock.lock();
            List<PaymentOrderBankDetail> listSaveBatch = getPaymentOrderBankDetailFromCmb(list);
            if (listSaveBatch == null || listSaveBatch.size() == 0) {
                log.info("对账流水详情没有数据需要保存");
            } else {
                boolean bo = paymentOrderBankDetailBatch.saveBatch(listSaveBatch);
                if (bo) {
                    log.info("对账流水详情数据保存成功");
                } else {
                    log.warn("对账流水详情数据保存失败");
                }
                return bo;
            }
        } catch (Exception e) {
            log.error("保存对账流水详情数据,出现异常：{}", e.getMessage());
        } /*finally {
                lock.forceUnlock();
            }*/
        // }
        return false;
    }

    /**
     * 招商银行获取需要保存的数据(待对账银行侧流水)
     *
     * @param list 招商支付对账明细数据
     * @return
     */
    private List<PaymentOrderBankDetail> getPaymentOrderBankDetailFromCmb(List<PaymentBankDataCmb> list) {
        List<PaymentOrderBankDetail> listSave = new ArrayList<>();
        for (PaymentBankDataCmb detailCmb : list) {
            PaymentOrderBankDetail paymentOrderBankDetail = getPaymentOrderBankDetail(detailCmb.getBankSerialNumber());
            if (paymentOrderBankDetail == null) {
                PaymentOrderBankDetail paymentOrderBankDetailAdd = new PaymentOrderBankDetail();
                paymentOrderBankDetailAdd.setMerOrderNo(detailCmb.getMerOrderNo());
                paymentOrderBankDetailAdd.setPayChannelOrderid(detailCmb.getBankSerialNumber());
                paymentOrderBankDetailAdd.setFlowId(detailCmb.getThirdOrderNo());
                paymentOrderBankDetailAdd.setPayWay(getPayWayCode(detailCmb.getPaymentWay()));
                paymentOrderBankDetailAdd.setTransactionType(getTransactionTypeCode(detailCmb.getTransactionType()));
                paymentOrderBankDetailAdd.setTransactionCurrency(detailCmb.getTradingCurrency());
                paymentOrderBankDetailAdd.setGoodsName(detailCmb.getGoodsName());
                paymentOrderBankDetailAdd.setPayTime(detailCmb.getTransactionDatetime());
                paymentOrderBankDetailAdd.setPayerInformation(detailCmb.getPayerInformation());
                paymentOrderBankDetailAdd.setPayingBank(detailCmb.getPayingBank());
                paymentOrderBankDetailAdd.setPayAmount(detailCmb.getTransactionAmount());
                paymentOrderBankDetailAdd.setServiceCharge(detailCmb.getServiceCharge());
                paymentOrderBankDetailAdd.setSettlementAmount(detailCmb.getSettlementAmount());
                paymentOrderBankDetailAdd.setRate(detailCmb.getRate());
                paymentOrderBankDetailAdd.setOriginalOrderAmount(detailCmb.getOriginalOrderAmount());
                paymentOrderBankDetailAdd.setFreeRechargeCouponAmount(detailCmb.getFreeRechargeCouponAmount());
                paymentOrderBankDetailAdd.setBusinessRedEnvelope(detailCmb.getEnterpriseRedPacketAmount());
                paymentOrderBankDetailAdd.setRefundBusinessRedEnvelope(detailCmb.getRefundAmountOfEnterpriseRedPacket());
                paymentOrderBankDetailAdd.setPlatformPreferentialAmount(detailCmb.getPlatformPreferentialAmount() == null ? 0 : detailCmb.getPlatformPreferentialAmount());
                paymentOrderBankDetailAdd.setStatementDate(detailCmb.getStatementDate());
                paymentOrderBankDetailAdd.setCompletionDate(detailCmb.getCompletionDate());
                paymentOrderBankDetailAdd.setOriginalMerOrderId(detailCmb.getOriginalMerchantOrderNo());
                paymentOrderBankDetailAdd.setOriginalPayChannelOrderid(detailCmb.getOriginalBankSerialNumber());
                paymentOrderBankDetailAdd.setOriginalFlowId(detailCmb.getOriginalThirdOrderNo());
                paymentOrderBankDetailAdd.setPayChannel(PaymentChannelEnum.OPENBANK_CMB.getCode());
                paymentOrderBankDetailAdd.setPayeeRemarks(detailCmb.getPayeeRemarks());
                paymentOrderBankDetailAdd.setPayerRemarks(detailCmb.getPayerRemarks());
                paymentOrderBankDetailAdd.setRefundRemarks(detailCmb.getRefundRemarks());
                paymentOrderBankDetailAdd.setBusinessType(detailCmb.getBusinessType());
                paymentOrderBankDetailAdd.setMerchantReservationDomain(detailCmb.getMerchantReservationDomain());
                paymentOrderBankDetailAdd.setClearingDate(detailCmb.getClearingDate());
                paymentOrderBankDetailAdd.setClearingAccount(detailCmb.getClearingAccount());
                paymentOrderBankDetailAdd.setClearingResult(detailCmb.getClearingResult());
                paymentOrderBankDetailAdd.setStoreName(detailCmb.getStoreName());
                paymentOrderBankDetailAdd.setStoreNo(detailCmb.getStoreNo());
                paymentOrderBankDetailAdd.setCashier(detailCmb.getCashier());
                listSave.add(paymentOrderBankDetailAdd);
            }
        }
        return listSave;
    }

    /**
     * 获取支付方式编码
     *
     * @param name 支付方式名称
     * @return
     */
    private String getPayWayCode(String name) {
        String transactionType = "";
        PayWayEnum payWayEnum = EnumUtil.getEnumByDesc(PayWayEnum.class, name);
        if (payWayEnum == null) {
            log.warn("支付方式(" + name + ")在枚举中不存在，请检查和添加！");
        } else {
            transactionType = payWayEnum.getCode();
        }
        return transactionType;
    }

    /**
     * 获取交易类型编码
     *
     * @param name 名称
     * @return
     */
    private String getTransactionTypeCode(String name) {
        String transactionType = "";
        TransactionTypeEnum transactionTypeEnum = EnumUtil.getEnumByDesc(TransactionTypeEnum.class, name);
        if (transactionTypeEnum == null) {
            log.warn("交易类型(" + name + ")在枚举中不存在，请检查和添加！");
        } else {
            transactionType = transactionTypeEnum.getCode();
        }
        return transactionType;
    }

    /**
     * 查询待对账银行侧流水
     *
     * @param payChannelOrderid 银行流水号
     * @return
     */
    private PaymentOrderBankDetail getPaymentOrderBankDetail(String payChannelOrderid) {
        QueryWrapper<PaymentOrderBankDetail> conditions = new QueryWrapper<>();
        conditions.eq("pay_channel_orderid", payChannelOrderid);
        return paymentOrderBankDetailMapper.selectOne(conditions);
    }

}
